package com.wans.guli.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.wans.guli.product.constant.em.AttrTypeEnum;
import com.wans.guli.product.entity.*;
import com.wans.guli.product.service.*;
import com.wans.guli.product.vo.*;
import com.wans.guli.product.vo.spu.save.Attr;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wans.guli.common.utils.PageUtils;
import com.wans.guli.common.utils.Query;

import com.wans.guli.product.dao.SkuInfoDao;


@Service("skuInfoService")
@SuppressWarnings("all")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    private AttrGroupService attrGroupService;
    @Autowired
    private AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    private AttrService attrService;
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private SpuInfoService spuInfoService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private ProductAttrValueServiceImpl productAttrValueService;
    @Autowired
    @Qualifier("productExecutor")
    private Executor executor;
    @Autowired
    private SpuInfoDescServiceImpl spuInfoDescService;

    @Override
    public PageUtils queryPage(SkuInfoVO skuInfoVO) {
        if (skuInfoVO == null) return null;
        if (skuInfoVO.getPage() == null) skuInfoVO.setPage("1");
        if (skuInfoVO.getLimit() == null) skuInfoVO.setLimit("10");

        // 创建分页参数
        HashMap<String, Object> pageParams = new HashMap<>();
        pageParams.put("page", skuInfoVO.getPage());
        pageParams.put("limit", skuInfoVO.getLimit());
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(pageParams),
                new QueryWrapper<SkuInfoEntity>().lambda()
                        .eq(skuInfoVO.getCatelogId() != null, SkuInfoEntity::getCatalogId, skuInfoVO.getCatelogId())
                        .eq(skuInfoVO.getBrandId() != null, SkuInfoEntity::getBrandId, skuInfoVO.getBrandId())
                        .le(skuInfoVO.getMax() != null, SkuInfoEntity::getPrice, skuInfoVO.getMax())
                        .ge(skuInfoVO.getMin() != null, SkuInfoEntity::getPrice, skuInfoVO.getMin())
                        .and(skuInfoVO.getKey() != null, wrapper -> {
                            wrapper.like(SkuInfoEntity::getSkuName, skuInfoVO.getKey())
                                    .or()
                                    .like(SkuInfoEntity::getSkuDesc, skuInfoVO.getKey());
                        })
                        .orderBy(skuInfoVO.getSidx() != null, (skuInfoVO.getOrder() != null && skuInfoVO.getOrder().equals("asc")), SkuInfoEntity::getSkuId)
        );

        return new PageUtils(page);
    }

    @Override
    public List<ProductSkuInfoRespVO> listSock(List<ProductSkuInfoRestVO> productSkuInfoRestVOList) {
        if (productSkuInfoRestVOList == null || productSkuInfoRestVOList.isEmpty())
            throw new RuntimeException("参数错误");

        return productSkuInfoRestVOList.stream().map(productSkuInfoRestVO -> {
            SkuInfoEntity skuInfoEntity = this.getById(productSkuInfoRestVO.getSkuId());
            if (skuInfoEntity == null || StrUtil.isEmpty(skuInfoEntity.getSkuName()))
                throw new RuntimeException("商品不存在");

            ProductSkuInfoRespVO productSkuInfoRespVO = new ProductSkuInfoRespVO();
            productSkuInfoRespVO.setSkuId(skuInfoEntity.getSkuId());
            productSkuInfoRespVO.setSkuName(skuInfoEntity.getSkuName());
            productSkuInfoRespVO.setWareId(productSkuInfoRestVO.getWareId());
            productSkuInfoRespVO.setStock(productSkuInfoRestVO.getStock());
            return productSkuInfoRespVO;
        }).collect(Collectors.toList());
    }

    /**
     * 根据skuId获取同级别所有sku信息
     *
     * @param skuId
     * @return
     */
    @Override
    @SneakyThrows
    public SkuItemVo listSpuInSkuInfo(Long skuId) {
        // 获取传递来的 sku 信息
        SkuInfoEntity skuInfoEntity = this.getById(skuId);
        // 获取spuId
        Long spuId = skuInfoEntity.getSpuId();
        // 获取spu的分类 id
        Long catId = skuInfoEntity.getCatalogId();
        // 获取 spuId下所有sku信息
        List<SkuInfoEntity> skuInfoEntities = this.lambdaQuery().eq(SkuInfoEntity::getSpuId, spuId).list();
        if (CollUtil.isEmpty(skuInfoEntities)) return null;
        List<Long> skuIds = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        String skuIdsStr = CollUtil.join(skuIds, ",");


        CompletableFuture<List<SpuItemAttrGroupVo>> spuItemAttrGroupVosCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 获取spu规格参数组合
            List<AttrGroupEntity> attrGroupEntities = attrGroupService.lambdaQuery()
                    .eq(AttrGroupEntity::getCatelogId, catId)
                    .list();
            // 获取所有属性组的组id
            List<Long> atteGroupIds = attrGroupEntities.stream().map(AttrGroupEntity::getAttrGroupId)
                    .distinct().collect(Collectors.toList());
            // 映射组id和组name
            Map<Long, String> attrGroupIdNameMap = attrGroupEntities.stream()
                    .collect(Collectors.toMap(AttrGroupEntity::getAttrGroupId, AttrGroupEntity::getAttrGroupName));
            // 获取所有属性组下的属性
            List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationService.lambdaQuery()
                    .in(AttrAttrgroupRelationEntity::getAttrGroupId, atteGroupIds)
                    .list();
            // 获取所有属性组下的属性id
            List<Long> attrIds = attrAttrgroupRelationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId)
                    .distinct().collect(Collectors.toList());
            // 映射属性id和组id
            Map<Long, Long> attrIdGroupIdMap = attrAttrgroupRelationEntities.stream()
                    .collect(Collectors.toMap(AttrAttrgroupRelationEntity::getAttrId, AttrAttrgroupRelationEntity::getAttrGroupId));
            // 获取所有属性id的 规格属性
            List<AttrEntity> attrEntities = attrService.lambdaQuery()
                    .in(AttrEntity::getAttrId, attrIds)
                    .eq(AttrEntity::getAttrType, AttrTypeEnum.BASE.getCode())
                    .list();
            // 以组name为key，SpuItemAttrGroupVo为value
            HashMap<String, SpuItemAttrGroupVo> groupAttrsMap = new HashMap<>();
            // 获取 SpuItemAttrGroupVo 列表
            List<SpuItemAttrGroupVo> spuItemAttrGroupVos = attrEntities.stream().map(attrEntity -> {
                SpuItemAttrGroupVo spuItemAttrGroupVo = new SpuItemAttrGroupVo();
                spuItemAttrGroupVo.setGroupName(attrGroupIdNameMap.get(attrIdGroupIdMap.get(attrEntity.getAttrId())));
                spuItemAttrGroupVo.setAttrs(new LinkedList<>());
                for (String value : attrEntity.getValueSelect().split(",")) {
                    Attr attr = BeanUtil.copyProperties(attrEntity, Attr.class);
                    attr.setAttrValue(value);
                    spuItemAttrGroupVo.getAttrs().add(attr);
                }
                return spuItemAttrGroupVo;
            }).collect(Collectors.toList());
            // 映射 groupName为key，SpuItemAttrGroupVo为value
            spuItemAttrGroupVos.forEach(spuItemAttrGroupVo -> {
                //groupAttrsMap.put(spuItemAttrGroupVo.getGroupName(), spuItemAttrGroupVo);
            });
            // 收集 groupAttrs
            //List<SpuItemAttrGroupVo> groupAttrs = new ArrayList<>(groupAttrsMap.values());

            return spuItemAttrGroupVos;
        }, executor);


        CompletableFuture<List<SkuItemSaleAttrVo>> saleAttrVosCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 获取spu销售属性组合 - 获取spuId下的所有sku
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = skuSaleAttrValueService.lambdaQuery()
                    .in(SkuSaleAttrValueEntity::getSkuId, skuIds)
                    .list();
            if (CollUtil.isEmpty(skuSaleAttrValueEntities)) throw new RuntimeException("没有找到对应的属性信息");
            skuSaleAttrValueEntities.forEach(saleAttrValues -> {

            });
            // 以attrId为key，skuIds为value
            Map<String, String> attrIdSkuIdsMap = new HashMap<>();
            // 以attrId为key，SpuItemAttrGroupVo为value
            Map<Long, SkuItemSaleAttrVo> attrIdGroupMap = new HashMap<>();
            skuSaleAttrValueEntities.forEach(saleAttrValues -> {
                // 操作 attrIdSkuIdsMap
                String string = attrIdSkuIdsMap.putIfAbsent(saleAttrValues.getAttrValue(), saleAttrValues.getSkuId().toString());
                if (string != null) {
                    // saleAttrValues.getAttrId() 存在
                    attrIdSkuIdsMap.put(saleAttrValues.getAttrValue(), string + "," + saleAttrValues.getSkuId().toString());
                }

                // 如果attrId不存在，则添加 使用 BeanUtil
                attrIdGroupMap.putIfAbsent(saleAttrValues.getAttrId(), BeanUtil.copyProperties(saleAttrValues, SkuItemSaleAttrVo.class));

                // 设置 attrValues
                // 1.1 获取 attrId 对应的 attrValues
                SkuItemSaleAttrVo spuItemAttrGroupVo = attrIdGroupMap.get(saleAttrValues.getAttrId());
                // 1.2 判断 attrValues 是否为空 - 为空就创建一个链表
                if (CollUtil.isEmpty(spuItemAttrGroupVo.getAttrValues()))
                    spuItemAttrGroupVo.setAttrValues(new LinkedList<>());
                // 1.3 添加 attrValues 数据
                AttrValueWithSkuIdVO attrValueWithSkuIdVO = new AttrValueWithSkuIdVO();
                attrValueWithSkuIdVO.setAttrValue(saleAttrValues.getAttrValue());

                // 添加 进 spuItemAttrGroupVo
                spuItemAttrGroupVo.getAttrValues().add(attrValueWithSkuIdVO);

            });
            // attrIdGroupMap 转换为 List
            List<SkuItemSaleAttrVo> saleAttrVos = new ArrayList<>(attrIdGroupMap.values());
            // 去重
            saleAttrVos.forEach(skuItemSaleAttrVo -> {
                ArrayList<AttrValueWithSkuIdVO> disSkuItemSaleAttrVo = skuItemSaleAttrVo.getAttrValues().stream().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(
                                () -> new TreeSet<>(Comparator.comparing(AttrValueWithSkuIdVO::getAttrValue))),
                        ArrayList::new
                ));
                skuItemSaleAttrVo.setAttrValues(disSkuItemSaleAttrVo);
            });
            // 给 attrIdGroupMap 相同的attrId 设置 setSkuIds
            for (SkuItemSaleAttrVo saleAttrVo : saleAttrVos) {
                saleAttrVo.getAttrValues().forEach(attrValueWithSkuIdVO -> {
                    attrValueWithSkuIdVO.setSkuIds(attrIdSkuIdsMap.get(attrValueWithSkuIdVO.getAttrValue()));
                });
            }

            return saleAttrVos;
        }, executor);


        // 获取 sku 图片列表
        // TODO 循环查库 - 优化 - 未做任何校验
        List<SkuImagesEntity> skuImagesEntities = skuImagesService.lambdaQuery()
                .in(SkuImagesEntity::getSkuId, skuIds).list();

        // 获取spu介绍信息 - 介绍大图 路径
        SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.lambdaQuery()
                .eq(SpuInfoDescEntity::getSpuId, spuId).one();

        // 等待 所有任务完成 - 这两个任务逻辑比较多 放入线程池异步执行
        CompletableFuture.allOf(spuItemAttrGroupVosCompletableFuture, saleAttrVosCompletableFuture);
        // 封装信息
        SkuItemVo itemVo = new SkuItemVo();
        itemVo.setInfo(skuInfoEntity);
        itemVo.setImages(skuImagesEntities);
        itemVo.setSaleAttr(saleAttrVosCompletableFuture.get());
        itemVo.setDesc(spuInfoDescEntity);
        itemVo.setGroupAttrs(spuItemAttrGroupVosCompletableFuture.get());
        //itemVo.setSeckillSkuVo(seckillSkuVo);

        return itemVo;
    }


    /**
     * 根据skuId获取同级别所有sku信息
     *
     * @param skuId 1
     * @return 1
     */
    public SkuItemVo listSpuInSkuInfoFail2(Long skuId) {
        // 获取传递来的 sku 信息
        SkuInfoEntity skuInfoEntity = this.getById(skuId);
        // 获取spuId
        Long spuId = skuInfoEntity.getSpuId();
        // 获取spu的分类 id
        Long catId = skuInfoEntity.getCatalogId();
        // 获取 spuId下所有sku信息
        List<SkuInfoEntity> skuInfoEntities = this.lambdaQuery().eq(SkuInfoEntity::getSpuId, spuId).list();
        if (CollUtil.isEmpty(skuInfoEntities)) return null;
        List<Long> skuIds = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        String skuIdsStr = CollUtil.join(skuIds, ",");


        // 获取spu规格参数组合
        List<AttrGroupEntity> attrGroupEntities = attrGroupService.lambdaQuery().eq(AttrGroupEntity::getCatelogId, catId).list();
        // TODO 循环查库 - 优化 - 未做任何校验
        HashMap<String, SkuItemSaleAttrVo> saleAttrInAttrId = new HashMap<>();
        List<SpuItemAttrGroupVo> groupAttrs = new LinkedList<>();
        List<Long> attrIds = new LinkedList<>();
        attrGroupEntities.forEach(attrGroupEntity -> {
            SpuItemAttrGroupVo spuItemAttrGroupVo = new SpuItemAttrGroupVo();
            attrAttrgroupRelationService.lambdaQuery().eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupEntity.getAttrGroupId()).list().forEach(attrAttrgroupRelationEntity -> {
                        AttrEntity attrEntity = attrService.lambdaQuery().eq(AttrEntity::getAttrId, attrAttrgroupRelationEntity.getAttrId()).one();
                        if (Objects.equals(attrEntity.getAttrType(), AttrTypeEnum.SALE.getCode())) {
                            // 销售属性 - 收集 attr id

                            String[] split = attrEntity.getValueSelect().split(";");
                            for (int i = 0; i < split.length; i++) {
                                attrIds.add(attrEntity.getAttrId());
                                AttrValueWithSkuIdVO attrValueWithSkuIdVO = new AttrValueWithSkuIdVO();
                                attrValueWithSkuIdVO.setAttrValue(split[i]);
                                attrValueWithSkuIdVO.setSkuIds(skuIdsStr);


                                saleAttrInAttrId.computeIfAbsent(String.valueOf(attrEntity.getAttrId()), k -> {
                                    SkuItemSaleAttrVo saleAttrVo = new SkuItemSaleAttrVo();
                                    saleAttrVo.setAttrId(attrEntity.getAttrId());
                                    saleAttrVo.setAttrName(attrEntity.getAttrName());
                                    return saleAttrVo;
                                });
                                List<AttrValueWithSkuIdVO> attrValues = saleAttrInAttrId.get(String.valueOf(attrEntity.getAttrId())).getAttrValues();
                                if (attrValues == null) attrValues = new LinkedList<>();

                                attrValues.add(attrValueWithSkuIdVO);

                                saleAttrInAttrId.get(String.valueOf(attrEntity.getAttrId())).setAttrValues(attrValues);
                            }


                        } else if (Objects.equals(attrEntity.getAttrType(), AttrTypeEnum.BASE.getCode())) {
                            // 规格参数
                            spuItemAttrGroupVo.setGroupName(attrGroupEntity.getAttrGroupName());
                            if (CollUtil.isEmpty(spuItemAttrGroupVo.getAttrs())) {
                                spuItemAttrGroupVo.setAttrs(new LinkedList<>());
                            }
                            Attr attr = BeanUtil.copyProperties(attrEntity, Attr.class);
                            spuItemAttrGroupVo.getAttrs().add(attr);
                            groupAttrs.add(spuItemAttrGroupVo);
                        }
                    }
            );
        });

/*        // 获取spu销售属性组合 - 获取spuId下的所有sku
        List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = skuSaleAttrValueService.lambdaQuery()
                .in(SkuSaleAttrValueEntity::getSkuId, skuIds)
                .in(SkuSaleAttrValueEntity::getAttrId, attrIds)
                .list();
        if(CollUtil.isEmpty(skuSaleAttrValueEntities)) throw new RuntimeException("没有找到对应的属性信息");
        skuInfoEntities.forEach( saleAttrValues-> {

        });*/


        // 获取 sku 图片
        // TODO 循环查库 - 优化 - 未做任何校验
        List<SkuImagesEntity> skuImagesEntities = skuImagesService.lambdaQuery()
                .in(SkuImagesEntity::getSkuId, skuIds).list();

        // 获取spu介绍
        SpuInfoEntity spuInfoEntity = spuInfoService.lambdaQuery().eq(SpuInfoEntity::getId, spuId).one();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
        spuInfoDescEntity.setDecript(spuInfoEntity.getSpuDescription());


        // 封装信息
        ArrayList<SkuItemSaleAttrVo> saleAttrVos = new ArrayList<>(saleAttrInAttrId.values());
        SkuItemVo itemVo = new SkuItemVo();
        itemVo.setInfo(skuInfoEntity);
        itemVo.setImages(skuImagesEntities);
        itemVo.setSaleAttr(saleAttrVos);
        itemVo.setDesc(spuInfoDescEntity);
        itemVo.setGroupAttrs(groupAttrs);
        //itemVo.setSeckillSkuVo(seckillSkuVo);

        return itemVo;
    }

}